<?php

// $Id: file.inc 24 2010-11-11 07:33:55Z mjohnson60@gmail.com $
//
// $Author: mjohnson60@gmail.com $
// $Date: 2010-11-10 22:31:26 -0500 (Wed, 10 Nov 2010) $
// 
// $Rev: 23 $
// 

/**
 * Finds all files that match a given mask in a given directory.
 * Directories and files beginning with a period are excluded; this
 * prevents hidden files and directories (such as SVN working directories)
 * from being scanned.
 *
 * @param $dir
 * The base directory for the scan, without trailing slash.
 * @param $mask
 * The regular expression of the files to find.
 * @param $nomask
 * An array of files/directories to ignore.
 * @param $callback
 * The callback function to call for each match.
 * @param $recurse
 * When TRUE, the directory scan will recurse the entire tree
 * starting at the provided directory.
 * @param $key
 * The key to be used for the returned array of files. Possible
 * values are "filename", for the path starting with $dir,
 * "basename", for the basename of the file, and "name" for the name
 * of the file without an extension.
 * @param $min_depth
 * Minimum depth of directories to return files from.
 * @param $depth
 * Current depth of recursion. This parameter is only used internally and should not be passed.
 *
 * @return
 * An associative array (keyed on the provided key) of objects with
 * "path", "basename", and "name" members corresponding to the
 * matching files.
 */
function file_scan_directory($dir, $mask, $nomask = array('.', '..', 'CVS'), $callback = 0, $recurse = TRUE, $key = 'filename', $min_depth = 0, $depth = 0)
{
	$key = (in_array($key, array('filename', 'basename', 'name')) ? $key : 'filename');
	$files = array();
	
	if (is_dir($dir) && $handle = opendir($dir))
	{
		while (FALSE !== ($file = readdir($handle)))
		{
			if (!in_array($file, $nomask) && $file[0] != '.')
			{
				if (is_dir("$dir/$file") && $recurse)
				{
					// Give priority to files in this folder by merging them in after any subdirectory files.
					$files = array_merge(file_scan_directory("$dir/$file", $mask, $nomask, $callback, $recurse, $key, $min_depth, $depth + 1), $files);
				}
				elseif ($depth >= $min_depth && ereg($mask, $file))
				{
					// Always use this match over anything already set in $files with the same $$key.
					$filename = "$dir/$file";
					$basename = basename($file);
					$name = substr($basename, 0, strrpos($basename, '.'));
					$files[$$key] = new stdClass();
					$files[$$key]->filename = $filename;
					$files[$$key]->basename = $basename;
					$files[$$key]->name = $name;
					if ($callback)
					{
						$callback($filename);
					}
				}
			}
		}
		
		closedir($handle);
	}
	
	return $files;
}
